<?php

namespace app\admin\service;

use app\model\ConsultOfflineResultModel;
use app\model\ConsultOnlineResultModel;
use app\model\ProxyEvaluationResultModel;
use app\model\RatingScaleQuestionAnswerModel;
use app\model\SelfEvaluationResultModel;
use app\model\TaskModel;
use app\model\TaskUserModel;
use app\model\TaskUserResultContinuityModel;
use app\model\TaskUserResultModel;
use app\model\UserModel;
use app\model\WarningReportRecordModel;
use OSS\Credentials\StaticCredentialsProvider;
use OSS\OssClient;
use PhpOffice\PhpSpreadsheet\IOFactory;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
use PhpOffice\PhpWord\TemplateProcessor;
use Swoole\Coroutine\Channel;
use Swoole\Coroutine\WaitGroup;
use think\facade\Log;
use think\Service;
use ZipArchive;

class ReportExportService extends Service
{
    public string $message;
    public int $line;
    public array $data;

    /**
     * 打包报告
     * @param $ids
     * @param $channel
     * @param $type
     * @return bool
     */
    public function pack($ids, $channel, $type): bool
    {
        try {
            $model = match ($channel) {
                "Self" => new SelfEvaluationResultModel(),
                "Task" => new TaskUserResultModel(),
                "Continuity" => new TaskUserResultContinuityModel(),
                "Proxy" => new ProxyEvaluationResultModel(),
                "ConsultOnline" => new ConsultOnlineResultModel(),
                "ConsultOffline" => new ConsultOfflineResultModel(),
                default => throw new \Exception('参数错误！'),
            };
            $data = $model->where('id', 'in', $ids)->field('id,word,pdf')->select()->toArray();
            if (!$data) throw new \Exception('没可导出得数据！');
            $zip = new ZipArchive();
            $ext = '.zip';
            $save_name = './export/pack' . date('Ym') . '/' . date('d') . '_' . time() . uniqid();
            folder_build(dirname($save_name . $ext));
            $zipFileName = $save_name . $ext; // 压缩包文件名
            if ($zip->open($zipFileName, ZipArchive::CREATE) !== TRUE)
                throw new \Exception('无法创建压缩文件');
            foreach ($data as $key => $item) {
                switch ($type) {
                    case 'word':
                        if (empty($item['word'])) break;
                        $fileContent = file_get_contents($item['word']);
                        $word_save_name = './export/pack' . date('Ym') . '/' . date('d') . '_' . time() . uniqid() . '.docx';
                        file_put_contents($word_save_name, $fileContent);
                        $zip->addFile($word_save_name, '测评报告' . $key . '.docx');
                        break;
                    case 'pdf':
                        if (empty($item['pdf'])) break;
                        $fileContent = file_get_contents($item['pdf']);
                        $pdf_save_name = './export/pack' . date('Ym') . '/' . date('d') . '_' . time() . uniqid() . '.pdf';
                        file_put_contents($pdf_save_name, $fileContent);
                        $zip->addFile($pdf_save_name, '测评报告' . $key . '.pdf');
                        break;
                    default:
                        throw new \Exception('参数错误！');
                }
            }
            $zip->close();
            $this->data = [
                'zipFileName' => oss($zipFileName, $ext)
            ];
            return true;
        } catch (\Exception $e) {
            $this->message = $e->getMessage();
            $this->line = $e->getLine();
            return false;
        }

    }

    /**
     * 打包报告
     * @param $where
     * @param $channel
     * @param $type
     * @return bool
     */
    public function pack2($where, $channel, $type): bool
    {
        try {
            $model = match ($channel) {
                "Self" => new SelfEvaluationResultModel(),
                "Task" => new TaskUserResultModel(),
                "Continuity" => new TaskUserResultContinuityModel(),
                "Proxy" => new ProxyEvaluationResultModel(),
                "ConsultOnline" => new ConsultOnlineResultModel(),
                "ConsultOffline" => new ConsultOfflineResultModel(),
                default => throw new \Exception('参数错误！'),
            };
            $data = $model->where($where)->field('id,word,pdf,concise_pdf,concise_word,uid')->with(['UserName'])->select()->toArray();
            if (!$data) throw new \Exception('没可导出得数据！');
            $zip = new ZipArchive();
            $ext = '.zip';
            $save_name = './export/pack' . date('Ym') . '/' . date('d') . '_' . time() . uniqid();
            folder_build(dirname($save_name . $ext));
            $zipFileName = $save_name . $ext; // 压缩包文件名
            if ($zip->open($zipFileName, ZipArchive::CREATE) !== TRUE)
                throw new \Exception('无法创建压缩文件');

            $wg = new WaitGroup();
            $pool = new Channel(10); // 限制最大并发为10
            $chunks = array_chunk($data, 30); // 每批30条
            $i = 0;
            foreach ($chunks as $chunk) {
                foreach ($chunk as $item) {
                    if (empty($item[$type])) {
                        continue;
                    }
                    $wg->add(); // 添加任务计数
                    go(function () use ($pool, $item, $type, $zip, $wg, $i) {
                        try {
                            $pool->push(true); // 占用一个协程槽位
                            // 流式获取OSS文件内容
                            // 直接写入ZIP不落盘
                            $zip->addFile('.' . $item[$type], $item['user_name'] . '_' . basename($item[$type]));
                        } catch (\Throwable $e) {
                            Log::channel('go')->error('压缩文件: ' . $e->getMessage());
                        } finally {
                            $pool->pop(); // 释放协程槽位
                            $wg->done();
                        }
                    });
                    $i++;
                }
                $wg->wait(); // 每批完成后等待
            }
            $zip->close();
            $this->data = [
                'zipFileName' => $zipFileName
            ];
            return true;
        } catch (\Exception $e) {
            $this->message = $e->getMessage();
            $this->line = $e->getLine();
            return false;
        }

    }

    /**
     * 流式压缩OSS文件到本地ZIP包
     * @param $where
     * @param $channel
     * @param $type
     * @return bool
     */
    public function streamCompress($where, $channel, $type): bool
    {
        try {
            $model = match ($channel) {
                "Self" => new SelfEvaluationResultModel(),
                "Task" => new TaskUserResultModel(),
                "Continuity" => new TaskUserResultContinuityModel(),
                "Proxy" => new ProxyEvaluationResultModel(),
                "ConsultOnline" => new ConsultOnlineResultModel(),
                "ConsultOffline" => new ConsultOfflineResultModel(),
                default => throw new \Exception('参数错误！'),
            };
            $data = $model->where($where)->field('id,word,pdf,concise_pdf,concise_word,uid')->with(['UserName'])->select()->toArray();
            if (!$data) throw new \Exception('没可导出得数据！');
            $ext = '.zip';
            $save_name = './export/pack' . date('Ym') . '/' . date('d') . '_' . time() . uniqid();
            folder_build(dirname($save_name . $ext));
            $zip = new ZipArchive();
            if ($zip->open($save_name . $ext, ZipArchive::CREATE) !== TRUE) {
                throw new \Exception('无法创建ZIP文件');
            }
            // 初始化OSS客户端
            $config = config('app.oss');
            // 获取AK和SK信息
            $accessKeyId = $config['access_key_id'];
            $accessKeySecret = $config['access_key_secret'];
            $provider = new StaticCredentialsProvider($accessKeyId, $accessKeySecret);
            $endpoint = $config['upload_url'];
            $ossConfig = array(
                "provider" => $provider,
                "endpoint" => $endpoint,
                "signatureVersion" => OssClient::OSS_SIGNATURE_VERSION_V4,
                "region" => "cn-beijing"
            );
            $ossClient = new OssClient($ossConfig);
            $wg = new WaitGroup();
            $pool = new Channel(10); // 限制最大并发为10
            $chunks = array_chunk($data, 30); // 每批30条
            foreach ($chunks as $chunk) {
                foreach ($chunk as $item) {
                    if (empty($item[$type])) {
                        continue;
                    }
                    $wg->add(); // 添加任务计数
                    $item[$type] = str_replace($config['static_url'] . '/', '', $item[$type]);
                    go(function () use ($pool, $ossClient, $config, $item, $type, $zip, $wg) {
                        try {
                            $pool->push(true); // 占用一个协程槽位
                            // 流式获取OSS文件内容
                            $stream = $ossClient->getObject(
                                $config['bucket_name'],
                                $item[$type]
                            );
                            // 直接写入ZIP不落盘
                            $zip->addFromString($item['user_name'] . '_' . basename($item[$type]), $stream);
                        } catch (\Throwable $e) {
                            Log::channel('go')->error('压缩文件: ' . $e->getMessage());
                        } finally {
                            $pool->pop(); // 释放协程槽位
                            $wg->done();
                        }
                    });
                }
                $wg->wait(); // 每批完成后等待
            }
            $zip->close();
            $this->data = [
                'zipFileName' => oss($save_name . $ext, $ext)
            ];
            return true;
        } catch (\Exception $e) {
            $this->message = $e->getMessage();
            $this->line = $e->getLine();
            return false;
        }
    }


    /**
     * 报告导出，四合一（教师）
     * @param $task_id
     * @return bool
     */
    public function fourInOne($task_id): bool
    {
        try {
            $TaskUserModel = new TaskUserModel();
            // 1. 分页查询配置（每页处理100条，可根据服务器性能调整）
            $pageSize = 100;
            $currentPage = 1;
            $total = $TaskUserModel->where('task_id', '=', $task_id)->count('id'); // 获取总条数
            if ($total == 0) {
                throw new \Exception('没有可导出的数据！');
            }
            $templatePath = app()->getRootPath() . 'public/export_template/four_in_one.xlsx';
            $spreadsheet = IOFactory::load($templatePath);
            $sheet = $spreadsheet->getActiveSheet(); // 获取当前活动工作表
            $key = 2;
            $RatingScaleQuestionAnswerModel = new RatingScaleQuestionAnswerModel();

            do {
                $data = $TaskUserModel->field('id,uid,rating_scale_id,result_id,is_finish')
                    ->where('task_id', '=', $task_id)->with([
                    'fourInOneRatingScale',
                    'fourInOneUser' => function ($query) {
                        $query->with([
                            'unitName'
                        ]);
                    },
                    'fourInOneTaskUserResult' => function ($query) {
                        $query->with([
                            'TaskFactorScore' => function ($query) {
                                $query->with(['fourInOneRatingScaleFactor']);
                            }
                        ]);
                    }
                ])->order('uid','asc')
                    ->page($currentPage, $pageSize)
                    ->select()
                    ->toArray();
                $userData = [];
                foreach ($data as $item) {
                    if (!isset($userData[$item['uid']])) {
                        $userData[$item['uid']] = [
                            'user_name' => $item['user_name'],
                            'username' => $item['username'],
                            'sex' => $item['sex'],
                            'unit_name' => $item['unit_name'],
                        ];
                    }
                    $userData[$item['uid']]['result'][] = $item;
                }

                foreach ($userData as $item) {
                    $sheet->setCellValue('B' . $key, $item['username']);
                    $sheet->setCellValue('C' . $key, $item['unit_name']);
                    $sheet->setCellValue('D' . $key, $item['user_name']);
                    $sheet->setCellValue('E' . $key, $item['sex'] == 1 ? '男' : '女');
//                $sheet->setCellValue('G'.$key, $item['']);

                    $is_valid = 1;//是否有效
                    $zsScore = 0;//自杀得分
                    $zfScore = 0;//总分得分
                    $ydfsScore = 0;//应对方式得分
                    $shzcScore = 0;//社会支持得分
                    $yyScore = 0;//抑郁得分
                    $jlScore = 0;//焦虑得分
                    $smzlScore = 0;//睡眠质量得分
                    $yxyzs = 0;//阳性因子数
                    $result_finish_used_time = 0;//测评用时

                    $is_finish = 0;
                    foreach ($item['result'] as $v) {
                        if ($v['is_finish'] != 1) continue;
                        $is_finish = 1;
                        $result_finish_used_time += $v['result_finish_used_time'] ?? 0;
                        switch ($v['rating_scale_previous_name']) {
                            case '症状自评量表(SCL-90)':
                                $sheet->setCellValue('F' . $key, date('Y-m-d H:i:s', $v['result_time']));
                                if ($v['is_valid'] == 1) {
                                    $sheet->setCellValue('I' . $key, '有效');
                                } else {
                                    $sheet->setCellValue('I' . $key, '可能无效');
                                    $is_valid = 0;
                                }
                                $question_answer = json_decode($v['question_answer'], true);
                                $zsScore = $RatingScaleQuestionAnswerModel->where('id', '=', $question_answer[15])->value('score');
                                $sheet->setCellValue('J' . $key, $zsScore);
                                foreach ($v['TaskFactorScore']??[] as $vv) {
                                    switch ($vv['factor_name']) {
                                        case '躯体化':
                                            $sheet->setCellValue('K' . $key, $vv['score']);
                                            $sheet->setCellValue('M' . $key, $vv['score'] < 3 ? '阴性' : '阳性');
                                            break;
                                        case '强迫症状':
                                            $sheet->setCellValue('N' . $key, $vv['score']);
                                            $sheet->setCellValue('P' . $key, $vv['score'] < 3 ? '阴性' : '阳性');
                                            break;
                                        case '人际关系敏感':
                                            $sheet->setCellValue('Q' . $key, $vv['score']);
                                            $sheet->setCellValue('S' . $key, $vv['score'] < 3 ? '阴性' : '阳性');
                                            break;
                                        case '抑郁':
                                            $yyScore = $vv['score'];
                                            $sheet->setCellValue('T' . $key, $vv['score']);
                                            $sheet->setCellValue('V' . $key, $vv['score'] < 3 ? '阴性' : '阳性');
                                            break;
                                        case '焦虑':
                                            $jlScore = $vv['score'];
                                            $sheet->setCellValue('W' . $key, $vv['score']);
                                            $sheet->setCellValue('Y' . $key, $vv['score'] < 3 ? '阴性' : '阳性');
                                            break;
                                        case '敌对':
                                            $sheet->setCellValue('Z' . $key, $vv['score']);
                                            $sheet->setCellValue('AB' . $key, $vv['score'] < 3 ? '阴性' : '阳性');
                                            break;
                                        case '恐怖':
                                            $sheet->setCellValue('AC' . $key, $vv['score']);
                                            $sheet->setCellValue('AE' . $key, $vv['score'] < 3 ? '阴性' : '阳性');
                                            break;
                                        case '偏执':
                                            $sheet->setCellValue('AF' . $key, $vv['score']);
                                            $sheet->setCellValue('AH' . $key, $vv['score'] < 3 ? '阴性' : '阳性');
                                            break;
                                        case '精神病性':
                                            $sheet->setCellValue('AI' . $key, $vv['score']);
                                            $sheet->setCellValue('AK' . $key, $vv['score'] < 3 ? '阴性' : '阳性');
                                            break;
                                        case '其他':
                                            $sheet->setCellValue('AL' . $key, $vv['score']);
                                            $sheet->setCellValue('AN' . $key, $vv['score'] < 3 ? '阴性' : '阳性');
                                            break;
                                        case '总分':
                                            $zfScore = $vv['score'];
                                            $sheet->setCellValue('AO' . $key, $vv['score']);
                                            $sheet->setCellValue('AQ' . $key, $vv['score'] <= 160 ? '阴性' : '阳性');
                                            break;
                                    }
                                    if ($vv['factor_name'] == '总分') {
                                        if ($vv['score'] > 160) {
                                            $yxyzs++;
                                        }
                                    } else {
                                        if ($vv['score'] >= 3) {
                                            $yxyzs++;
                                        }
                                    }
                                }
                                break;
                            case '简易应对方式问卷':
                                foreach ($v['TaskFactorScore']??[] as $vv) {
                                    switch ($vv['factor_name']) {
                                        case '积极应对':
                                            $sheet->setCellValue('AS' . $key, $vv['score']);
                                            break;
                                        case '消极应对':
                                            $sheet->setCellValue('AT' . $key, $vv['score']);
                                            break;
                                        case '应对方式':
                                            $ydfsScore = $vv['score'];
                                            $sheet->setCellValue('AU' . $key, $vv['score']);
                                            $sheet->setCellValue('AV' . $key, $vv['score'] <= 0 ? '消极' : '积极');
                                            break;
                                    }
                                }
                                break;
                            case '阿森斯失眠量表':
                                foreach ($v['TaskFactorScore']??[] as $vv) {
                                    $smzlScore = $vv['score'];
                                    if ($vv['score'] < 4) {
                                        $sheet->setCellValue('AY' . $key, '无睡眠障碍');
                                    } elseif ($vv['score'] <= 6) {
                                        $sheet->setCellValue('AY' . $key, '疑似失眠');
                                    } else {
                                        $sheet->setCellValue('AY' . $key, '失眠');
                                    }
                                    $sheet->setCellValue('AZ' . $key, $vv['score']);
                                    break;
                                }
                                break;
                            case '领悟社会支持量表(PSSS)':
                                foreach ($v['TaskFactorScore']??[] as $vv) {
                                    switch ($vv['factor_name']) {
                                        case '家庭支持':
                                            $sheet->setCellValue('BB' . $key, $vv['score']);
                                            break;
                                        case '朋友支持':
                                            $sheet->setCellValue('BD' . $key, $vv['score']);
                                            break;
                                        case '其它支持':
                                            $sheet->setCellValue('BF' . $key, $vv['score']);
                                            break;
                                        case '社会支持':
                                            $shzcScore = $vv['score'];
                                            if ($vv['score'] <= 30) {
                                                $sheet->setCellValue('BI' . $key, '低支持');
                                            } elseif ($vv['score'] <= 60) {
                                                $sheet->setCellValue('BI' . $key, '中支持');
                                            } else {
                                                $sheet->setCellValue('BI' . $key, '高支持');
                                            }
                                            $sheet->setCellValue('BH' . $key, $vv['score']);
                                            break;
                                    }
                                }
                                break;
                        }
                    }
                    if ($is_finish != 1) continue;
                    $sheet->setCellValue('G' . $key, $result_finish_used_time);
                    if ($is_valid == 0) {
                        $warning = '可能无效';
                    } else {
                        if (
                            $zsScore > 3 || // ① 自杀倾向 > 3
                            ($zfScore > 160 && $ydfsScore <= 0 && $shzcScore <= 30) || // ② 总分>160 且 应对方式≤0 且 社会支持≤30
                            $yyScore > 3 || // ③ 抑郁 > 3
                            $jlScore > 3    // ④ 焦虑 > 3
                        ) {
                            $warning = '红色';
                            if ($zsScore > 3) {
                                $warning .= '①';
                            }
                            if ($zfScore > 160 && $ydfsScore <= 0 && $shzcScore <= 30) {
                                $warning .= '②';
                            }
                            if ($yyScore > 3) {
                                $warning .= '③';
                            }
                            if ($jlScore > 3) {
                                $warning .= '④';
                            }
                        } // 第三步：黄色预警判断（非红色 + 满足任意一项）
                        else if ($jlScore > 2 || $yyScore > 2) {
                            $warning = '黄色';
                        } // 第四步：蓝色预警判断（非红/黄 + 满足任意一项）
                        else if ($zfScore > 160 || $smzlScore > 12 || $yxyzs > 3) {
                            $warning = '蓝色';
                        } else {
                            $warning = '无风险';
                        }
                    }
                    $sheet->setCellValue('H' . $key, $warning);
                    $key++;
                }
                // 释放当前页内存
                unset($data, $userData);
                $currentPage++;
            } while (($currentPage - 1) * $pageSize < $total); // 循环直到所有数据处理完成

            $writer = new Xlsx($spreadsheet);
            $ext = '.xlsx';
            $save_name = './export/four_in_one' . date('Ym') . '/' . date('d') . '_' . time() . uniqid();
            $file_path = dirname($save_name . $ext);
            folder_build($file_path);
            $writer->save($save_name . $ext);
            $this->data['fileUrl'] = match (env("UPLOAD_TYPE")) {
                'local' => $save_name . $ext,
                'oss' => oss($save_name . $ext, $ext),
                default => throw new \Exception('系统配置错误！'),
            };
            return true;
        } catch (\Exception $e) {
            $this->message = $e->getMessage();
            $this->line = $e->getLine();
            return false;
        }
    }

    /**
     * 报告导出，四合一（小学生）
     * @param $task_id
     * @param $unit_id
     * @return bool
     */
    public function fourInOne2($task_id,$unit_id): bool
    {
        try {
            $TaskUserModel = new TaskUserModel();
            // 1. 分页查询配置（每页处理100条，可根据服务器性能调整）
            $pageSize = 100;
            $currentPage = 1;
            $total = $TaskUserModel->where('task_id', '=', $task_id)->count('id'); // 获取总条数
            if ($total == 0) {
                throw new \Exception('没有可导出的数据！');
            }
            $templatePath = app()->getRootPath() . 'public/export_template/four_in_one2.xlsx';
            $spreadsheet = IOFactory::load($templatePath);
            $sheet = $spreadsheet->getActiveSheet(); // 获取当前活动工作表
            $key = 2;
            $UserService = new UserService($this->app);
            $department = $UserService->getDepartmentAffiliationAll($unit_id);
            do {
                $data = $TaskUserModel->field('id,uid,rating_scale_id,result_id,is_finish')
                    ->where('task_id', '=', $task_id)->with([
                    'fourInOneRatingScale',
                    'fourInOneUser',
                    'fourInOneTaskUserResult' => function ($query) {
                        $query->with([
                            'TaskFactorScore' => function ($query) {
                                $query->with(['fourInOneRatingScaleFactor']);
                            }
                        ]);
                    }
                ])->order('uid','asc')->page($currentPage, $pageSize)
                    ->select()
                    ->toArray();
                $userData = [];
                foreach ($data as $item) {
                    if (!isset($userData[$item['uid']])) {
                        $userData[$item['uid']] = [
                            'user_name' => $item['user_name'],
                            'username' => $item['username'],
                            'sex' => $item['sex'],
                            'department_id' => $department[$item['department_id']]['all_name']??'--',
                            'unit_name' => $item['unit_name'],
                        ];
                    }
                    $userData[$item['uid']]['result'][] = $item;
                }

                foreach ($userData as $item) {
                    $sheet->setCellValue('A' . $key, $item['username']);
                    $sheet->setCellValue('B' . $key, $item['department_id']);
                    $sheet->setCellValue('C' . $key, $item['user_name']);
                    $sheet->setCellValue('D' . $key, $item['sex'] == 1 ? '男' : '女');

                    $polygraphScore = 0;//测谎得分
                    $result_finish_used_time = 0;//测评用时

                    $yytyScore = 0;//抑郁体验得分
                    $jltyScore = 0;//焦虑体验得分
                    $qtjxScore = 0;//躯体情绪得分
                    $ztmydScore = 0;//总体满意度得分
                    $ydqxScore = 0;//应对倾向得分
                    $gjScore = 0;//攻击得分
                    $shzcScore = 0;//社会支持得分
                    $jtshScore = 0;//家庭生活得分
                    $tbjwScore = 0;//同伴交往得分
                    $xxshScore = 0;//学校生活得分
                    $shhjScore = 0;//生活环境得分
                    $zwrsScore = 0;//自我认识得分
                    $qfshScore = 0;//欺负受害得分

                    $is_finish = 0;

                    foreach ($item['result'] as $v) {
                        if ($v['is_finish'] != 1) continue;
                        $is_finish = 1;
                        $result_finish_used_time += $v['result_finish_used_time'] ?? 0;
                        $rating_scale_previous_name[] = $v['rating_scale_previous_name'];
                        switch ($v['rating_scale_previous_name']) {
                            case '少儿主观生活质量问卷（LSLQ）':
                                $sheet->setCellValue('E' . $key, date('Y-m-d H:i:s', $v['result_time']));
                                foreach ($v['TaskFactorScore']??[] as $vv) {
                                    switch ($vv['factor_name']) {
                                        case '测谎题':
                                            $polygraphScore += $vv['score'];
                                            break;
                                        case '家庭生活':
                                            $jtshScore = $vv['score'];
                                            $sheet->setCellValue('L' . $key, $vv['score']);
                                            break;
                                        case '同伴交往':
                                            $tbjwScore = $vv['score'];
                                            $sheet->setCellValue('N' . $key, $vv['score']);
                                            break;
                                        case '学校生活':
                                            $xxshScore = $vv['score'];
                                            $sheet->setCellValue('P' . $key, $vv['score']);
                                            break;
                                        case '生活环境':
                                            $shhjScore = $vv['score'];
                                            $sheet->setCellValue('R' . $key, $vv['score']);
                                            break;
                                        case '自我认识':
                                            $zwrsScore = $vv['score'];
                                            $sheet->setCellValue('T' . $key, $vv['score']);
                                            break;
                                        case '躯体情绪':
                                            $qtjxScore = $vv['score'];
                                            $sheet->setCellValue('V' . $key, $vv['score']);
                                            break;
                                        case '焦虑体验':
                                            $jltyScore = $vv['score'];
                                            $sheet->setCellValue('X' . $key, $vv['score']);
                                            break;
                                        case '抑郁体验':
                                            $yytyScore = $vv['score'];
                                            $sheet->setCellValue('Z' . $key, $vv['score']);
                                            break;
                                        case '总体满意度':
                                            $ztmydScore = $vv['score'];
                                            $sheet->setCellValue('AB' . $key, $vv['score']);
                                            break;
                                    }
                                }
                                break;
                            case '简易应对方式问卷':
                                foreach ($v['TaskFactorScore']??[] as $vv) {
                                    switch ($vv['factor_name']) {
                                        case '积极应对':
                                            $sheet->setCellValue('AD' . $key, $vv['score']);
                                            break;
                                        case '消极应对':
                                            $sheet->setCellValue('AF' . $key, $vv['score']);
                                            break;
                                        case '应对方式':
                                            $ydqxScore = $vv['score'];
                                            $sheet->setCellValue('AH' . $key, $vv['score']);
                                            break;
                                    }
                                }
                                break;
                            case '特拉华受害欺负量表（DBVSS）':
                                foreach ($v['TaskFactorScore']??[] as $vv) {
                                    switch ($vv['factor_name']) {
                                        case '测谎题':
                                            $polygraphScore += $vv['score'];
                                            break;
                                        case '言语欺负':
                                            $sheet->setCellValue('AI' . $key, $vv['score']);
                                            break;
                                        case '社会关系欺负':
                                            $sheet->setCellValue('AK' . $key, $vv['score']);
                                            break;
                                        case '身体欺负':
                                            $sheet->setCellValue('AM' . $key, $vv['score']);
                                            break;
                                        case '欺负受害':
                                            $qfshScore = $vv['score'];
                                            $sheet->setCellValue('AO' . $key, $vv['score']);
                                            break;
                                    }
                                }
                                break;
                            case '领悟社会支持量表(PSSS)':
                                foreach ($v['TaskFactorScore']??[] as $vv) {
                                    switch ($vv['factor_name']) {
                                        case '家庭支持':
                                            $sheet->setCellValue('AQ' . $key, $vv['score']);
                                            break;
                                        case '朋友支持':
                                            $sheet->setCellValue('AS' . $key, $vv['score']);
                                            break;
                                        case '其它支持':
                                            $sheet->setCellValue('AU' . $key, $vv['score']);
                                            break;
                                        case '社会支持':
                                            $shzcScore = $vv['score'];
                                            $sheet->setCellValue('AW' . $key, $vv['score']);
                                            break;
                                    }
                                }
                                break;
                            case '攻击问卷（AQ-12）':
                                foreach ($v['TaskFactorScore']??[] as $vv) {
                                    switch ($vv['factor_name']) {
                                        case '躯体攻击':
                                            $sheet->setCellValue('AY' . $key, $vv['score']);
                                            break;
                                        case '语言攻击':
                                            $sheet->setCellValue('BA' . $key, $vv['score']);
                                            break;
                                        case '愤怒':
                                            $sheet->setCellValue('BC' . $key, $vv['score']);
                                            break;
                                        case '敌意':
                                            $sheet->setCellValue('BE' . $key, $vv['score']);
                                            break;
                                        case '总分':
                                            $gjScore = $vv['score'];
                                            $sheet->setCellValue('BG' . $key, $vv['score']);
                                            break;
                                    }
                                }
                                break;
                        }
                    }
                    if ($is_finish != 1) continue;

                    $sheet->setCellValue('G' . $key, implode('、',$rating_scale_previous_name??''));
                    $sheet->setCellValue('F' . $key, $result_finish_used_time);
                    $sheet->setCellValue('I' . $key, $polygraphScore);
                    if ($polygraphScore >= 8){
                        $sheet->setCellValue('J' . $key, '可能无效');
                    }else{
                        $sheet->setCellValue('J' . $key, '有效');
                    }
                    // 1. 红色预警判断（高风险）
                    if (
                        // 1.1 红色①：抑郁体验 < 2
                        $yytyScore < 2 ||
                        // 1.2 红色②：复合条件
                        (
                            ($jltyScore < 2 || $qtjxScore < 2 || $ztmydScore < 20) &&
                            $ydqxScore < 0
                        )
                    ) {
                        $warning = '红色';
                        $redMark = '';
                        if ($yytyScore < 2) $redMark .= '①';
                        if (($jltyScore < 2 || $qtjxScore < 2 || $ztmydScore < 20) && $ydqxScore < 0) $redMark .= '②';
                        $warning .= $redMark;
                    }
                    // 2. 黄色预警判断（中风险，非红色）
                    else if (
                        // 2.1 黄色①：抑郁体验<3 或 焦虑体验<3
                        $yytyScore < 3 || $jltyScore < 3 ||
                        // 2.2 黄色②：攻击>40 + 抑郁<4 + 焦虑<4
                        (
                            $gjScore > 40 &&
                            $yytyScore < 4 &&
                            $jltyScore < 4
                        ) ||
                        // 2.3 黄色③：抑郁<4 + 焦虑<4 + 社会支持<30
                        (
                            $yytyScore < 4 &&
                            $jltyScore < 4 &&
                            $shzcScore < 30
                        )
                    ) {
                        $warning = '黄色';
                        $yellowMark = '';
                        if ($yytyScore < 3 || $jltyScore < 3) $yellowMark .= '①';
                        if ($gjScore > 40 && $yytyScore < 4 && $jltyScore < 4) $yellowMark .= '②';
                        if ($yytyScore < 4 && $jltyScore < 4 && $shzcScore < 30) $yellowMark .= '③';
                        $warning .= $yellowMark;
                    }
                    // 3. 蓝色预警判断（低风险，非红/黄）
                    else if (
                        // 3.1 蓝色①：家庭/同伴/学校/环境/自我认识任一项<10 或 社会支持<30
                        (
                            $jtshScore < 10 || $tbjwScore < 10 ||
                            $xxshScore < 10 || $shhjScore < 10 ||
                            $zwrsScore < 10 || $shzcScore < 30
                        ) ||
                        // 3.2 蓝色②：欺负受害 ≥ 40
                        $qfshScore >= 40 ||
                        // 3.3 蓝色③：攻击总分 > 40
                        $gjScore > 40
                    ) {
                        $warning = '蓝色';
                        $blueMark = '';
                        if ($jtshScore < 10 || $tbjwScore < 10 || $xxshScore < 10 || $shhjScore < 10 || $zwrsScore < 10 || $shzcScore < 30) $blueMark .= '①';
                        if ($qfshScore >= 40) $blueMark .= '②';
                        if ($gjScore > 40) $blueMark .= '③';
                        $warning .= $blueMark;
                    }
                    // 4. 无风险
                    else {
                        $warning = '绿色（无风险）';
                    }
                    $sheet->setCellValue('H' . $key, $warning);
                    $key++;
                }
                // 释放当前页内存
                unset($data, $userData);
                $currentPage++;
            } while (($currentPage - 1) * $pageSize < $total); // 循环直到所有数据处理完成


            $writer = new Xlsx($spreadsheet);
            $ext = '.xlsx';
            $save_name = './export/four_in_one' . date('Ym') . '/' . date('d') . '_' . time() . uniqid();
            $file_path = dirname($save_name . $ext);
            folder_build($file_path);
            $writer->save($save_name . $ext);
            $this->data['fileUrl'] = match (env("UPLOAD_TYPE")) {
                'local' => $save_name . $ext,
                'oss' => oss($save_name . $ext, $ext),
                default => throw new \Exception('系统配置错误！'),
            };
            return true;
        } catch (\Exception $e) {
            $this->message = $e->getMessage();
            $this->line = $e->getLine();
            return false;
        }
    }

    /**
     * 报告导出，四合一（中学生）
     * @param $task_id
     * @param $unit_id
     * @return bool
     */
    public function fourInOne3($task_id,$unit_id): bool
    {
        try {
            $TaskUserModel = new TaskUserModel();
            // 1. 分页查询配置（每页处理100条，可根据服务器性能调整）
            $pageSize = 100;
            $currentPage = 1;
            $total = $TaskUserModel->where('task_id', '=', $task_id)->count('id'); // 获取总条数
            if ($total == 0) {
                throw new \Exception('没有可导出的数据！');
            }
            $templatePath = app()->getRootPath() . 'public/export_template/four_in_one3.xlsx';
            $spreadsheet = IOFactory::load($templatePath);
            $sheet = $spreadsheet->getActiveSheet(); // 获取当前活动工作表
            $key = 2;

            $UserService = new UserService($this->app);
            $department = $UserService->getDepartmentAffiliationAll($unit_id);
            do {
                $data = $TaskUserModel->field('id,uid,rating_scale_id,result_id,is_finish')
                    ->where('task_id', '=', $task_id)->with([
                    'fourInOneRatingScale',
                    'fourInOneUser',
                    'fourInOneTaskUserResult' => function ($query) {
                        $query->with([
                            'TaskFactorScore' => function ($query) {
                                $query->with(['fourInOneRatingScaleFactor']);
                            }
                        ]);
                    }
                ])->order('uid','asc')->page($currentPage, $pageSize)
                    ->select()
                    ->toArray();
                $userData = [];
                foreach ($data as $item) {
                    if (!isset($userData[$item['uid']])) {
                        $userData[$item['uid']] = [
                            'user_name' => $item['user_name'],
                            'username' => $item['username'],
                            'sex' => $item['sex'],
                            'department_id' => $department[$item['department_id']]['all_name']??'--',
                            'unit_name' => $item['unit_name'],
                        ];
                    }
                    $userData[$item['uid']]['result'][] = $item;
                }

                foreach ($userData as $item) {
                    $sheet->setCellValue('A' . $key, $item['username']);
                    $sheet->setCellValue('B' . $key, $item['department_id']);
                    $sheet->setCellValue('C' . $key, $item['user_name']);
                    $sheet->setCellValue('D' . $key, $item['sex'] == 1 ? '男' : '女');

                    $result_finish_used_time = 0;//测评用时

                    $is_finish = 0;

                    foreach ($item['result'] as $v) {
                        if ($v['is_finish'] != 1) continue;
                        $is_finish = 1;
                        $result_finish_used_time += $v['result_finish_used_time'] ?? 0;
                        switch ($v['rating_scale_previous_name']) {
                            case '中学生心理健康量表（MMHI）':
                                $sheet->setCellValue('E' . $key, date('Y-m-d H:i:s', $v['result_time']));
                                foreach ($v['TaskFactorScore']??[] as $vv) {
                                    switch ($vv['factor_name']) {
                                        case '强迫':
                                            $sheet->setCellValue('U' . $key, $vv['score']);
                                            break;
                                        case '偏执':
                                            $sheet->setCellValue('Q' . $key, $vv['score']);
                                            break;
                                        case '敌对':
                                            $sheet->setCellValue('G' . $key, $vv['score']);
                                            break;
                                        case '人际敏感':
                                            $sheet->setCellValue('Y' . $key, $vv['score']);
                                            break;
                                        case '抑郁':
                                            $sheet->setCellValue('AY' . $key, $vv['score']);
                                            break;
                                        case '焦虑':
                                            $sheet->setCellValue('M' . $key, $vv['score']);
                                            break;
                                        case '学习压力感':
                                            $sheet->setCellValue('AS' . $key, $vv['score']);
                                            break;
                                        case '适应性不良':
                                            $sheet->setCellValue('AI' . $key, $vv['score']);
                                            break;
                                        case '情绪波动性':
                                            $sheet->setCellValue('W' . $key, $vv['score']);
                                            break;
                                        case '心理不平衡':
                                            $sheet->setCellValue('AQ' . $key, $vv['score']);
                                            break;
                                    }
                                }
                                break;
                            case '简易应对方式问卷':
                                foreach ($v['TaskFactorScore']??[] as $vv) {
                                    switch ($vv['factor_name']) {
                                        case '积极应对':
                                            $sheet->setCellValue('I' . $key, $vv['score']);
                                            break;
                                        case '消极应对':
                                            $sheet->setCellValue('AO' . $key, $vv['score']);
                                            break;
                                        case '应对方式':
                                            $sheet->setCellValue('AU' . $key, $vv['score']);
                                            break;
                                    }
                                }
                                break;
                            case '特拉华受害欺负量表（DBVSS）':
                                foreach ($v['TaskFactorScore']??[] as $vv) {
                                    switch ($vv['factor_name']) {
                                        case '言语欺负':
                                            $sheet->setCellValue('AW' . $key, $vv['score']);
                                            break;
                                        case '社会关系欺负':
                                            $sheet->setCellValue('AE' . $key, $vv['score']);
                                            break;
                                        case '身体欺负':
                                            $sheet->setCellValue('AG' . $key, $vv['score']);
                                            break;
                                        case '欺负受害':
                                            $sheet->setCellValue('BE' . $key, $vv['score']);
                                            break;
                                    }
                                }
                                break;
                            case '青少年生活事件量表（ASLEC）':
                                foreach ($v['TaskFactorScore']??[] as $vv) {
                                    switch ($vv['factor_name']) {
                                        case '应激总量':
                                            $sheet->setCellValue('BA' . $key, $vv['score']);
                                            break;
                                        case '人际压力事件':
                                            $sheet->setCellValue('AA' . $key, $vv['score']);
                                            break;
                                        case '适应性事件':
                                            $sheet->setCellValue('AK' . $key, $vv['score']);
                                            break;
                                        case '受惩罚事件':
                                            $sheet->setCellValue('AM' . $key, $vv['score']);
                                            break;
                                        case '学习压力事件':
                                            $sheet->setCellValue('AU' . $key, $vv['score']);
                                            break;
                                        case '丧失事件':
                                            $sheet->setCellValue('AC' . $key, $vv['score']);
                                            break;
                                    }
                                }
                                break;
                            case '领悟社会支持量表(PSSS)':
                                foreach ($v['TaskFactorScore']??[] as $vv) {
                                    switch ($vv['factor_name']) {
                                        case '家庭支持':
                                            $sheet->setCellValue('K' . $key, $vv['score']);
                                            break;
                                        case '朋友支持':
                                            $sheet->setCellValue('O' . $key, $vv['score']);
                                            break;
                                        case '其它支持':
                                            $sheet->setCellValue('S' . $key, $vv['score']);
                                            break;
                                        case '社会支持':
                                            $sheet->setCellValue('BC' . $key, $vv['score']);
                                            break;
                                    }
                                }
                                break;
                        }
                    }
                    if ($is_finish != 1) continue;
                    $sheet->setCellValue('F' . $key, $result_finish_used_time);

                    $key++;
                }
                // 释放当前页内存
                unset($data, $userData);
                $currentPage++;
            } while (($currentPage - 1) * $pageSize < $total); // 循环直到所有数据处理完成


            $writer = new Xlsx($spreadsheet);
            $ext = '.xlsx';
            $save_name = './export/four_in_one' . date('Ym') . '/' . date('d') . '_' . time() . uniqid();
            $file_path = dirname($save_name . $ext);
            folder_build($file_path);
            $writer->save($save_name . $ext);
            $this->data['fileUrl'] = match (env("UPLOAD_TYPE")) {
                'local' => $save_name . $ext,
                'oss' => oss($save_name . $ext, $ext),
                default => throw new \Exception('系统配置错误！'),
            };
            return true;
        } catch (\Exception $e) {
            $this->message = $e->getMessage();
            $this->line = $e->getLine();
            return false;
        }
    }


    /**
     * 预警列表导出（xlsx）
     * @param $id
     * @param $unit_id
     * @return bool
     */
    public function warning($id, $unit_id): bool
    {
        try {
            $WarningReportRecordModel = new WarningReportRecordModel();
            $data = $WarningReportRecordModel->where('id', 'in', $id)->with([
                'taskResult' => function ($query) {
                    $query->with([
                        'user',
                        'RatingScaleName',
                        'warningName',
                        'FactorScore' => function ($query) {
                            $query->with(['fourInOneRatingScaleFactor']);
                        }
                    ]);
                },
                'selfResult' => function ($query) {
                    $query->with([
                        'user',
                        'RatingScaleName',
                        'warningName',
                        'FactorScore' => function ($query) {
                            $query->with(['fourInOneRatingScaleFactor']);
                        }
                    ]);
                },
                'proxyResult' => function ($query) {
                    $query->with([
                        'user',
                        'RatingScaleName',
                        'warningName',
                        'FactorScore' => function ($query) {
                            $query->with(['fourInOneRatingScaleFactor']);
                        }
                    ]);
                }
            ])->select()->toArray();
            $strArr = ['H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
                'AA', 'AB', 'AC', 'AD', 'AE', 'AF', 'AG', 'AH', 'AI', 'AJ', 'AK', 'AL', 'AM', 'AN', 'AO', 'AP', 'AQ', 'AR', 'AS', 'AT', 'AU', 'AV', 'AW', 'AX', 'AY', 'AZ',
                'BA', 'BB', 'BC', 'BD', 'BE', 'BF', 'BG', 'BH', 'BI', 'BJ', 'BK', 'BL', 'BM', 'BN', 'BO', 'BP', 'BQ', 'BR', 'BS', 'BT', 'BU', 'BV', 'BW', 'BX', 'BY', 'BZ',
                'CA', 'CB', 'CC', 'CD', 'CE', 'CF', 'CG', 'CH', 'CI', 'CJ', 'CK', 'CL', 'CM', 'CN', 'CO', 'CP', 'CQ', 'CR', 'CS', 'CT', 'CU', 'CV', 'CW', 'CX', 'CY', 'CZ',
                'DA', 'DB', 'DC', 'DD', 'DE', 'DF', 'DG', 'DH', 'DI', 'DJ', 'DK', 'DL', 'DM', 'DN', 'DO', 'DP', 'DQ', 'DR', 'DS', 'DT', 'DU', 'DV', 'DW', 'DX', 'DY', 'DZ',
                'EA', 'EB', 'EC', 'ED', 'EE', 'EF', 'EG', 'EH', 'EI', 'EJ', 'EK', 'EL', 'EM', 'EN', 'EO', 'EP', 'EQ', 'ER', 'ES', 'ET', 'EU', 'EV', 'EW', 'EX', 'EY', 'EZ',
                'FA', 'FB', 'FC', 'FD', 'FE', 'FF', 'FG', 'FH', 'FI', 'FJ', 'FK', 'FL', 'FM', 'FN', 'FO', 'FP', 'FQ', 'FR', 'FS', 'FT', 'FU', 'FV', 'FW', 'FX', 'FY', 'FZ',
                'GA', 'GB', 'GC', 'GD', 'GE', 'GF', 'GG', 'GH', 'GI', 'GJ', 'GK', 'GL', 'GM', 'GN', 'GO', 'GP', 'GQ', 'GR', 'GS', 'GT', 'GU', 'GV', 'GW', 'GX', 'GY', 'GZ'];
            $UserService = new UserService($this->app);
            $DepartmentAffiliationAll = $UserService->getDepartmentAffiliationAll($unit_id);
            $ratingScaleData = [];
            foreach ($data as $item) {
                $result = match ($item['source']) {
                    1 => $item['taskResult'],
                    2 => $item['selfResult'],
                    3 => $item['proxyResult'],
                    default => throw new \Exception('系统错误！'),
                };
                if (empty($result)) continue;
                $ratingScaleData[$result['rating_scale_name']][] = $result;
            }
            unset($data);
            // 创建新的Spreadsheet对象
            $spreadsheet = new Spreadsheet();
            $i = 0;
            foreach ($ratingScaleData as $key => $item) {
                if ($i > 0) {
                    $spreadsheet->createSheet();
                }
                $sheet = $spreadsheet->setActiveSheetIndex($i);
                $i++;
                // 设置工作表标题
                $sheet->setTitle($key);
                // 设置单元格数据
                $sheet->setCellValue('A1', '名称');
                $sheet->setCellValue('B1', '账号');
                $sheet->setCellValue('C1', '性别');
                $sheet->setCellValue('D1', '年龄');
                $sheet->setCellValue('E1', '所在部门');
                $sheet->setCellValue('F1', '量表名称');
                $sheet->setCellValue('G1', '预警等级');
                foreach ($item as $k => $v) {
                    $k = $k + 2;
                    $sheet->setCellValue('A' . $k, $v['user_name']);
                    $sheet->setCellValue('B' . $k, $v['username'] . ' ');
                    $sheet->setCellValue('C' . $k, $v['sex'] == 1 ? '男' : '女');
                    $sheet->setCellValue('D' . $k, $v['age']);
                    $sheet->setCellValue('E' . $k, $DepartmentAffiliationAll[$v['department_id']]['all_name'] ?? '--');
                    $sheet->setCellValue('F' . $k, $v['rating_scale_name']);
                    $sheet->setCellValue('G' . $k, $v['warning_name']);
                    foreach ($v['FactorScore'] as $kk => $vv) {
                        if ($k == 2) {
                            $sheet->setCellValue($strArr[$kk] . '1', $vv['factor_name']);
                        }
                        $sheet->setCellValue($strArr[$kk] . $k, $vv['score']);
                    }
                }
            }
            $writer = new Xlsx($spreadsheet);
            $ext = '.xlsx';
            $save_name = './export/warning' . date('Ym') . '/' . date('d') . '_' . time() . uniqid();
            folder_build(dirname($save_name . $ext));
            $writer->save($save_name . $ext);
            $this->data['fileUrl'] = match (env("UPLOAD_TYPE")) {
                'local' => $save_name . $ext,
                'oss' => oss($save_name . $ext, $ext),
                default => throw new \Exception('系统配置错误！'),
            };
            return true;
        } catch (\Exception $e) {
            $this->message = $e->getMessage();
            $this->line = $e->getLine();
            return false;
        }
    }

    public function taskAll($param): bool|string
    {
        try {
            $task_id = $param['id'];
            $TaskModel = new TaskModel();
            $TaskUserResultModel = new TaskUserResultModel();
            $UserModel = new UserModel();
            $TaskUserModel = new TaskUserModel();
            $taskInfo = $TaskModel->with([
                'unitName'
            ])->find($task_id);
            $uid = $TaskUserResultModel->where('task_id', '=', $task_id)->distinct(true)->column('uid');
            $warning_uid = $TaskUserResultModel->where([
                ['task_id', '=', $task_id],
                ['is_warning', '=', 1]
            ])->distinct(true)->column('uid');
            $resultCount = $TaskUserResultModel->where('task_id', '=', $task_id)->count();
            $resultWarningCount = $TaskUserResultModel->where([
                ['task_id', '=', $task_id],
                ['is_warning', '=', 1]
            ])->count();
            $resultValidCount = $TaskUserResultModel->where([
                ['task_id', '=', $task_id],
                ['is_valid', '=', 0]
            ])->count();
            $user_answer_num = $TaskUserResultModel->where([
                ['task_id', '=', $task_id],
                ['answer_role', '=', 1]
            ])->count();

            $involved_num = count($uid);
            $involved_boy_num = $UserModel->where([
                ['id', 'in', $uid],
                ['sex', '=', 1]
            ])->count();
            $involved_girl_num = $involved_num - $involved_boy_num;
            $not_uid = $TaskUserModel->where([
                ['task_id', '=', $task_id],
                ['uid', 'not in', $uid]
            ])->distinct(true)->column('uid');
            $not_involved_boy_num = $UserModel->where([
                ['id', 'in', $not_uid],
                ['sex', '=', 1]
            ])->count();
            $part_rate = round(($involved_num / $taskInfo['user_count']) * 100, 2);
            $templateProcessor = new TemplateProcessor(app()->getRootPath() . 'public/export_template/group_report_all.docx');
            $templateProcessor->setValue('task_name', $taskInfo['name']);
            $templateProcessor->setValue('unit_name', $taskInfo['unit_name']);
            $templateProcessor->setValue('task_start_time', $taskInfo['start_time'] ? date('Y-m-d H:i:s', $taskInfo['start_time']) : '--');
            $templateProcessor->setValue('task_end_time', $taskInfo['end_time'] ? date('Y-m-d H:i:s', $taskInfo['end_time']) : '--');
            $templateProcessor->setValue('target_num', $taskInfo['user_count']);
            $templateProcessor->setValue('total_complete_rate', $taskInfo['user_complete_rate'] . '%');
            $templateProcessor->setValue('part_object', $taskInfo['unit_name'] . $taskInfo['user_count']);
            $templateProcessor->setValue('involved_num', $involved_num);
            $templateProcessor->setValue('part_rate', $part_rate . '%');
            $templateProcessor->setValue('involved_boy_num', $involved_boy_num);
            $templateProcessor->setValue('involved_girl_num', $involved_girl_num);
            $templateProcessor->setValue('not_involved_num', $taskInfo['user_count'] - $involved_num);
            $templateProcessor->setValue('unpart_rate', round((($taskInfo['user_count'] - $involved_num) / $taskInfo['user_count']) * 100, 2) . '%');

            $templateProcessor->setValue('not_involved_boy_num', $not_involved_boy_num);
            $templateProcessor->setValue('not_involved_girl_num', $taskInfo['user_count'] - $involved_num - $not_involved_boy_num);


            $templateProcessor->setValue('report_num', $resultCount);
            $templateProcessor->setValue('user_answer_num', $user_answer_num);
            $templateProcessor->setValue('self_answer_rate', round(($user_answer_num / $resultCount) * 100, 2) . '%');

            $templateProcessor->setValue('normal_report_num', $resultCount - $resultWarningCount - $resultValidCount);
            $templateProcessor->setValue('normal_report_rate', round((($resultCount - $resultWarningCount - $resultValidCount)/$resultCount)*100,2).'%');
            $templateProcessor->setValue('invalid_report_num', $resultValidCount);
            $templateProcessor->setValue('invalid_report_rate', round(($resultValidCount/$resultCount)*100,2).'%');
            $templateProcessor->setValue('warning_report_num', $resultWarningCount);
            $templateProcessor->setValue('warning_report_rate', round(($resultWarningCount/$resultCount)*100,2).'%');

            $warning_report_boy_num = $UserModel->where([
                ['id', 'in', $warning_uid],
                ['sex', '=', 1]
            ])->count();
            $warning_report_girl_num = $resultWarningCount - $warning_report_boy_num;
            $templateProcessor->setValue('warning_report_boy_num', $warning_report_boy_num);
            $templateProcessor->setValue('warning_report_boy_rate', $resultWarningCount?round(($warning_report_boy_num / $resultWarningCount) * 100, 2):0 . '%');
            $templateProcessor->setValue('warning_report_girl_num', $warning_report_girl_num);
            $templateProcessor->setValue('warning_report_girl_rate', $resultWarningCount?round(($warning_report_girl_num / $resultWarningCount) * 100, 2):0 . '%');
            $upload = new \app\common\Upload();
            // 设置上传类型和文件大小
            $upload = $upload->defaultConfig();
            if (!empty($param['list'])) {
                $templateProcessor->cloneBlock('rating_scale', count($param['list']), true, true);
                foreach ($param['list'] as $key => $value) {
                    $index = $key + 1;
                    $templateProcessor->setValue('rating_scale_name#' . $index, $value['rating_scale_name']);
                    $img = $upload->upload($value['img'], 'base64', '.png');
                    $templateProcessor->setImageValue('rating_scale_chart_img#' . $index, ['path' => $img, 'width' => 550, 'height' => 280]);
                }
            }else{
                $templateProcessor->cloneBlock('rating_scale', 0, true, true);
            }
            if (!empty($param['peopleBar'])){
                $img = $upload->upload($param['peopleBar'], 'base64', '.png');
                $templateProcessor->setImageValue('peopleBar', ['path' => $img, 'width' => 550, 'height' => 280]);
            }else{
                $templateProcessor->setValue('peopleBar', '');
            }
            if (!empty($param['reportPie'])){
                $img = $upload->upload($param['reportPie'], 'base64', '.png');
                $templateProcessor->setImageValue('chart_img', ['path' => $img, 'width' => 550, 'height' => 280]);
            }else{
                $templateProcessor->setValue('chart_img', '');
            }
            // 保存修改后的文档
            $ext = '.docx';
            $save_name = './export/group_report_all' . date('Ym') . '/' . date('d') . '_' . time() . uniqid();
            folder_build(dirname($save_name . $ext));
            $templateProcessor->saveAs($save_name . $ext);
            $this->data['fileUrl'] = match (env("UPLOAD_TYPE")) {
                'local' => $save_name . $ext,
                'oss' => oss($save_name . $ext, $ext),
                default => throw new \Exception('系统配置错误！'),
            };
            return true;
        } catch (\Exception $e) {
            $this->message = $e->getMessage();
            $this->line = $e->getLine();
            return false;
        }
    }


    /**
     * 任务报告列表导出（xlsx）
     * @param $where
     * @param $unit_id
     * @return bool
     */
    public function taskExcel($where, $unit_id): bool
    {
        try {
            $TaskUserResultModel = new TaskUserResultModel();
            $data = $TaskUserResultModel->where($where)->with([
                'user2',
                'RatingScaleName',
                'warningName',
                'FactorScore' => function ($query) {
                    $query->with(['fourInOneRatingScaleFactor']);
                }
            ])->select()->toArray();
            $strArr = ['H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
                'AA', 'AB', 'AC', 'AD', 'AE', 'AF', 'AG', 'AH', 'AI', 'AJ', 'AK', 'AL', 'AM', 'AN', 'AO', 'AP', 'AQ', 'AR', 'AS', 'AT', 'AU', 'AV', 'AW', 'AX', 'AY', 'AZ',
                'BA', 'BB', 'BC', 'BD', 'BE', 'BF', 'BG', 'BH', 'BI', 'BJ', 'BK', 'BL', 'BM', 'BN', 'BO', 'BP', 'BQ', 'BR', 'BS', 'BT', 'BU', 'BV', 'BW', 'BX', 'BY', 'BZ',
                'CA', 'CB', 'CC', 'CD', 'CE', 'CF', 'CG', 'CH', 'CI', 'CJ', 'CK', 'CL', 'CM', 'CN', 'CO', 'CP', 'CQ', 'CR', 'CS', 'CT', 'CU', 'CV', 'CW', 'CX', 'CY', 'CZ',
                'DA', 'DB', 'DC', 'DD', 'DE', 'DF', 'DG', 'DH', 'DI', 'DJ', 'DK', 'DL', 'DM', 'DN', 'DO', 'DP', 'DQ', 'DR', 'DS', 'DT', 'DU', 'DV', 'DW', 'DX', 'DY', 'DZ',
                'EA', 'EB', 'EC', 'ED', 'EE', 'EF', 'EG', 'EH', 'EI', 'EJ', 'EK', 'EL', 'EM', 'EN', 'EO', 'EP', 'EQ', 'ER', 'ES', 'ET', 'EU', 'EV', 'EW', 'EX', 'EY', 'EZ',
                'FA', 'FB', 'FC', 'FD', 'FE', 'FF', 'FG', 'FH', 'FI', 'FJ', 'FK', 'FL', 'FM', 'FN', 'FO', 'FP', 'FQ', 'FR', 'FS', 'FT', 'FU', 'FV', 'FW', 'FX', 'FY', 'FZ',
                'GA', 'GB', 'GC', 'GD', 'GE', 'GF', 'GG', 'GH', 'GI', 'GJ', 'GK', 'GL', 'GM', 'GN', 'GO', 'GP', 'GQ', 'GR', 'GS', 'GT', 'GU', 'GV', 'GW', 'GX', 'GY', 'GZ'];
            $UserService = new UserService($this->app);
            $DepartmentAffiliationAll = $UserService->getDepartmentAffiliationAll($unit_id);
            // 创建新的Spreadsheet对象
            $spreadsheet = new Spreadsheet();
            $sheet = $spreadsheet->setActiveSheetIndex(0);
            // 设置工作表标题
            $sheet->setTitle('任务报告记录');
            // 设置单元格数据
            $sheet->setCellValue('A1', '名称');
            $sheet->setCellValue('B1', '账号');
            $sheet->setCellValue('C1', '性别');
            $sheet->setCellValue('D1', '年龄');
            $sheet->setCellValue('E1', '所在部门');
            $sheet->setCellValue('F1', '量表名称');
            $sheet->setCellValue('G1', '预警等级');
            foreach ($data as $k => $v) {
                $k = $k + 2;
                $sheet->setCellValue('A' . $k, $v['user_name']);
                $sheet->setCellValue('B' . $k, $v['username'] . ' ');
                $sheet->setCellValue('C' . $k, $v['sex'] == 1 ? '男' : '女');
                $sheet->setCellValue('D' . $k, $v['age']);
                $sheet->setCellValue('E' . $k, $DepartmentAffiliationAll[$v['department_id']]['all_name'] ?? '--');
                $sheet->setCellValue('F' . $k, $v['rating_scale_name']);
                $sheet->setCellValue('G' . $k, $v['warning_name']);
                foreach ($v['FactorScore'] as $kk => $vv) {
                    if ($k == 2) {
                        $sheet->setCellValue($strArr[$kk] . '1', $vv['factor_name']);
                    }
                    $sheet->setCellValue($strArr[$kk] . $k, $vv['score']);
                }
            }
            $writer = new Xlsx($spreadsheet);
            $ext = '.xlsx';
            $save_name = './export/warning' . date('Ym') . '/' . date('d') . '_' . time() . uniqid();
            folder_build(dirname($save_name . $ext));
            $writer->save($save_name . $ext);
            $this->data['fileUrl'] = match (env("UPLOAD_TYPE")) {
                'local' => $save_name . $ext,
                'oss' => oss($save_name . $ext, $ext),
                default => throw new \Exception('系统配置错误！'),
            };
            return true;
        } catch (\Exception $e) {
            $this->message = $e->getMessage();
            $this->line = $e->getLine();
            return false;
        }
    }

    /**
     * 自我报告列表导出（xlsx）
     * @param $where
     * @param $unit_id
     * @return bool
     */
    public function selfExcel($where, $unit_id): bool
    {
        try {
            $SelfEvaluationResultModel = new SelfEvaluationResultModel();
            $data = $SelfEvaluationResultModel->where($where)->with([
                'user2',
                'RatingScaleName',
                'warningName',
                'FactorScore' => function ($query) {
                    $query->with(['fourInOneRatingScaleFactor']);
                }
            ])->select()->toArray();
            $strArr = ['H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
                'AA', 'AB', 'AC', 'AD', 'AE', 'AF', 'AG', 'AH', 'AI', 'AJ', 'AK', 'AL', 'AM', 'AN', 'AO', 'AP', 'AQ', 'AR', 'AS', 'AT', 'AU', 'AV', 'AW', 'AX', 'AY', 'AZ',
                'BA', 'BB', 'BC', 'BD', 'BE', 'BF', 'BG', 'BH', 'BI', 'BJ', 'BK', 'BL', 'BM', 'BN', 'BO', 'BP', 'BQ', 'BR', 'BS', 'BT', 'BU', 'BV', 'BW', 'BX', 'BY', 'BZ',
                'CA', 'CB', 'CC', 'CD', 'CE', 'CF', 'CG', 'CH', 'CI', 'CJ', 'CK', 'CL', 'CM', 'CN', 'CO', 'CP', 'CQ', 'CR', 'CS', 'CT', 'CU', 'CV', 'CW', 'CX', 'CY', 'CZ',
                'DA', 'DB', 'DC', 'DD', 'DE', 'DF', 'DG', 'DH', 'DI', 'DJ', 'DK', 'DL', 'DM', 'DN', 'DO', 'DP', 'DQ', 'DR', 'DS', 'DT', 'DU', 'DV', 'DW', 'DX', 'DY', 'DZ',
                'EA', 'EB', 'EC', 'ED', 'EE', 'EF', 'EG', 'EH', 'EI', 'EJ', 'EK', 'EL', 'EM', 'EN', 'EO', 'EP', 'EQ', 'ER', 'ES', 'ET', 'EU', 'EV', 'EW', 'EX', 'EY', 'EZ',
                'FA', 'FB', 'FC', 'FD', 'FE', 'FF', 'FG', 'FH', 'FI', 'FJ', 'FK', 'FL', 'FM', 'FN', 'FO', 'FP', 'FQ', 'FR', 'FS', 'FT', 'FU', 'FV', 'FW', 'FX', 'FY', 'FZ',
                'GA', 'GB', 'GC', 'GD', 'GE', 'GF', 'GG', 'GH', 'GI', 'GJ', 'GK', 'GL', 'GM', 'GN', 'GO', 'GP', 'GQ', 'GR', 'GS', 'GT', 'GU', 'GV', 'GW', 'GX', 'GY', 'GZ'];
            $UserService = new UserService($this->app);
            $DepartmentAffiliationAll = $UserService->getDepartmentAffiliationAll($unit_id);
            $ratingScaleData = [];
            foreach ($data as $item) {
                $ratingScaleData[$item['rating_scale_name']][] = $item;
            }
            unset($data);
            // 创建新的Spreadsheet对象
            $spreadsheet = new Spreadsheet();
            $i = 0;
            foreach ($ratingScaleData as $key => $item) {
                if ($i > 0) {
                    $spreadsheet->createSheet();
                }
                $sheet = $spreadsheet->setActiveSheetIndex($i);
                $i++;
                // 设置工作表标题
                $sheet->setTitle($key);
                // 设置单元格数据
                $sheet->setCellValue('A1', '名称');
                $sheet->setCellValue('B1', '账号');
                $sheet->setCellValue('C1', '性别');
                $sheet->setCellValue('D1', '年龄');
                $sheet->setCellValue('E1', '所在部门');
                $sheet->setCellValue('F1', '量表名称');
                $sheet->setCellValue('G1', '预警等级');
                foreach ($item as $k => $v) {
                    $k = $k + 2;
                    $sheet->setCellValue('A' . $k, $v['user_name']);
                    $sheet->setCellValue('B' . $k, $v['username'] . ' ');
                    $sheet->setCellValue('C' . $k, $v['sex'] == 1 ? '男' : '女');
                    $sheet->setCellValue('D' . $k, $v['age']);
                    $sheet->setCellValue('E' . $k, $DepartmentAffiliationAll[$v['department_id']]['all_name'] ?? '--');
                    $sheet->setCellValue('F' . $k, $v['rating_scale_name']);
                    $sheet->setCellValue('G' . $k, $v['warning_name']);
                    foreach ($v['FactorScore'] as $kk => $vv) {
                        if ($k == 2) {
                            $sheet->setCellValue($strArr[$kk] . '1', $vv['factor_name']);
                        }
                        $sheet->setCellValue($strArr[$kk] . $k, $vv['score']);
                    }
                }
            }

            $writer = new Xlsx($spreadsheet);
            $ext = '.xlsx';
            $save_name = './export/warning' . date('Ym') . '/' . date('d') . '_' . time() . uniqid();
            folder_build(dirname($save_name . $ext));
            $writer->save($save_name . $ext);
            $this->data['fileUrl'] = match (env("UPLOAD_TYPE")) {
                'local' => $save_name . $ext,
                'oss' => oss($save_name . $ext, $ext),
                default => throw new \Exception('系统配置错误！'),
            };
            return true;
        } catch (\Exception $e) {
            $this->message = $e->getMessage();
            $this->line = $e->getLine();
            return false;
        }
    }

    /**
     * 他人代测报告列表导出（xlsx）
     * @param $where
     * @param $unit_id
     * @return bool
     */
    public function proxyExcel($where, $unit_id): bool
    {
        try {
            $ProxyEvaluationResultModel = new ProxyEvaluationResultModel();
            $data = $ProxyEvaluationResultModel->where($where)->with([
                'user2',
                'RatingScaleName',
                'warningName',
                'FactorScore' => function ($query) {
                    $query->with(['fourInOneRatingScaleFactor']);
                }
            ])->select()->toArray();
            $strArr = ['H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
                'AA', 'AB', 'AC', 'AD', 'AE', 'AF', 'AG', 'AH', 'AI', 'AJ', 'AK', 'AL', 'AM', 'AN', 'AO', 'AP', 'AQ', 'AR', 'AS', 'AT', 'AU', 'AV', 'AW', 'AX', 'AY', 'AZ',
                'BA', 'BB', 'BC', 'BD', 'BE', 'BF', 'BG', 'BH', 'BI', 'BJ', 'BK', 'BL', 'BM', 'BN', 'BO', 'BP', 'BQ', 'BR', 'BS', 'BT', 'BU', 'BV', 'BW', 'BX', 'BY', 'BZ',
                'CA', 'CB', 'CC', 'CD', 'CE', 'CF', 'CG', 'CH', 'CI', 'CJ', 'CK', 'CL', 'CM', 'CN', 'CO', 'CP', 'CQ', 'CR', 'CS', 'CT', 'CU', 'CV', 'CW', 'CX', 'CY', 'CZ',
                'DA', 'DB', 'DC', 'DD', 'DE', 'DF', 'DG', 'DH', 'DI', 'DJ', 'DK', 'DL', 'DM', 'DN', 'DO', 'DP', 'DQ', 'DR', 'DS', 'DT', 'DU', 'DV', 'DW', 'DX', 'DY', 'DZ',
                'EA', 'EB', 'EC', 'ED', 'EE', 'EF', 'EG', 'EH', 'EI', 'EJ', 'EK', 'EL', 'EM', 'EN', 'EO', 'EP', 'EQ', 'ER', 'ES', 'ET', 'EU', 'EV', 'EW', 'EX', 'EY', 'EZ',
                'FA', 'FB', 'FC', 'FD', 'FE', 'FF', 'FG', 'FH', 'FI', 'FJ', 'FK', 'FL', 'FM', 'FN', 'FO', 'FP', 'FQ', 'FR', 'FS', 'FT', 'FU', 'FV', 'FW', 'FX', 'FY', 'FZ',
                'GA', 'GB', 'GC', 'GD', 'GE', 'GF', 'GG', 'GH', 'GI', 'GJ', 'GK', 'GL', 'GM', 'GN', 'GO', 'GP', 'GQ', 'GR', 'GS', 'GT', 'GU', 'GV', 'GW', 'GX', 'GY', 'GZ'];
            $UserService = new UserService($this->app);
            $DepartmentAffiliationAll = $UserService->getDepartmentAffiliationAll($unit_id);

            $ratingScaleData = [];
            foreach ($data as $item) {
                $ratingScaleData[$item['rating_scale_name']][] = $item;
            }
            unset($data);
            // 创建新的Spreadsheet对象
            $spreadsheet = new Spreadsheet();
            $i = 0;
            foreach ($ratingScaleData as $key => $item) {
                if ($i > 0) {
                    $spreadsheet->createSheet();
                }
                $sheet = $spreadsheet->setActiveSheetIndex($i);
                $i++;
                // 设置工作表标题
                $sheet->setTitle($key);

                // 设置单元格数据
                $sheet->setCellValue('A1', '名称');
                $sheet->setCellValue('B1', '账号');
                $sheet->setCellValue('C1', '性别');
                $sheet->setCellValue('D1', '年龄');
                $sheet->setCellValue('E1', '所在部门');
                $sheet->setCellValue('F1', '量表名称');
                $sheet->setCellValue('G1', '预警等级');
                foreach ($item as $k => $v) {
                    $k = $k + 2;
                    $sheet->setCellValue('A' . $k, $v['user_name']);
                    $sheet->setCellValue('B' . $k, $v['username'] . ' ');
                    $sheet->setCellValue('C' . $k, $v['sex'] == 1 ? '男' : '女');
                    $sheet->setCellValue('D' . $k, $v['age']);
                    $sheet->setCellValue('E' . $k, $DepartmentAffiliationAll[$v['department_id']]['all_name'] ?? '--');
                    $sheet->setCellValue('F' . $k, $v['rating_scale_name']);
                    $sheet->setCellValue('G' . $k, $v['warning_name']);
                    foreach ($v['FactorScore'] as $kk => $vv) {
                        if ($k == 2) {
                            $sheet->setCellValue($strArr[$kk] . '1', $vv['factor_name']);
                        }
                        $sheet->setCellValue($strArr[$kk] . $k, $vv['score']);
                    }
                }

            }

            $writer = new Xlsx($spreadsheet);
            $ext = '.xlsx';
            $save_name = './export/warning' . date('Ym') . '/' . date('d') . '_' . time() . uniqid();
            folder_build(dirname($save_name . $ext));
            $writer->save($save_name . $ext);
            $this->data['fileUrl'] = match (env("UPLOAD_TYPE")) {
                'local' => $save_name . $ext,
                'oss' => oss($save_name . $ext, $ext),
                default => throw new \Exception('系统配置错误！'),
            };
            return true;
        } catch (\Exception $e) {
            $this->message = $e->getMessage();
            $this->line = $e->getLine();
            return false;
        }
    }


}